const crypto = require('crypto');
const moment = require('moment');

module.exports = function(sequelize, DataTypes){
    var User = sequelize.define('AdminUser', {
        id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        },
        user_name: {
            type: DataTypes.STRING(20),
            allowNull: false,
            get() {
                return this.getDataValue('user_name');
            },
            set(user_name) {
                this.setDataValue('user_name', user_name);
                this.setDataValue('name', user_name);
            }
        },
        password: {
            type: DataTypes.STRING(32),
            allowNull: false,
            get() {
                return this.getDataValue('password');
            },
            set(password) {
                var salt = crypto.createHash('md5').update(Math.random().toString()).digest('hex');
                this.setDataValue('salt', salt);
                this.setDataValue('password', this.encryptPassword(password));
            }
        },
        province: {
            type: DataTypes.BIGINT(20)
        },
        city: {
            type: DataTypes.BIGINT(20)
        },
        country: {
            type: DataTypes.BIGINT(20)
        },
        name: {
            type: DataTypes.STRING(40)
        },
        mail: {
            type: DataTypes.STRING(40)
        },
        tel: {
            type: DataTypes.STRING(11)
        },
        sex: {
            type: DataTypes.STRING(1)
        },
        birthday: {
            type: DataTypes.DATE
        },
        channel_authorize_status: {
            type: DataTypes.TINYINT(4)
        },
        salt: {
            type: DataTypes.STRING(40)
        },
        own_supplier: {
            type: DataTypes.BIGINT(20)
        },
        creator_id: {
            type: DataTypes.BIGINT(20),
            defaultValue: 0,
            allowNull: false
        },
        created_at: {
            type: DataTypes.DATE,
            defaultValue: new Date(),
            allowNull: false,
            get() {
                return moment(this.getDataValue('created_at')).format('YYYY-MM-DD HH:mm:ss');
            }
        },
        modified_id: {
            type: DataTypes.BIGINT(20),
            defaultValue: 0,
            allowNull: false
        },
        modified_at: {
            type: DataTypes.DATE,
            defaultValue: new Date(),
            allowNull: false,
            get() {
                return moment(this.getDataValue('modified_at')).format('YYYY-MM-DD HH:mm:ss');
            }
        },
        is_del: {
            type: DataTypes.TINYINT(1),
            defaultValue: 0,
            allowNull: false
        }
    },{
        timestamps: false,
        freezeTableName: true,
        tableName: 'system_user',
    });

    User.schema("public");

    User.toParams = toParams;

    User.prototype.toParams = function(opts) {
        return toParams(this, opts);
    };

    User.associate = function (model) {
        addUserRoles(User, model.AdminRole);
    };

    User.destroyUsers = async function(user_ids) {
        return sequelize.transaction().then(function (t) {
            this.t = t;
            return User.update({
                is_del: 1
            },{
                transaction: t,
                where: {
                    id: user_ids
                }
            });
        }).then(function() {
            return sequelize.query("DELETE FROM system_user_role WHERE user_id in ("+user_ids.join(',')+");", {
                type: sequelize.QueryTypes.DELETE,
                transaction: this.t
            });
        }).then(function() {
            return this.t.commit();
        }).catch(function (err) {
            return this.t.rollback();
        });
    };

    User.prototype.encryptPassword = function(password) {
        return md5_data(password, this.get('salt'));
    };

    User.prototype.verifyPassword = function(password) {
        return this.encryptPassword(password) === this.get('password');
    };

    // 同步模型到数据库
    User.sync({force: false}).then(function () {

    });

    return User;
};

function toParams(model, opts) {
    var transObj = {
        id: model.id,
        is: model.id + "_",
        user_name: model.user_name,
        name: model.name,
        mail: model.mail,
        phone: model.tel,
        sex: model.sex == "1" ? "男" : "女",
        created_at: model.created_at ? moment(model.created_at).format("YYYY-MM-DD HH:mm:ss") : "",
        modified_at: model.modified_at != "0000-00-00 00:00:00" ? moment(model.modified_at).format("YYYY-MM-DD HH:mm:ss") : "",
        birthday: model.birthday ? moment(model.birthday).format("YYYY-MM-DD") : ""
    };
    return transObj;
}

function md5_data(password, salt) {
    var data = password;
    if (!!salt) {
        data = data + "_" + salt;
    }
    return crypto.createHash("md5").update(data).digest('hex');
}

function addUserRoles(user, role) {
    user.belongsToMany(role, {
        as: 'UserRoles',
        through: 'system_user_role',
        timestamps: false,
        foreignKey: {
            name: 'user_id',
            allowNull: false
        },
        otherKey: {
            name: 'role_id',
            allowNull: false
        }
    });
}

